﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NGDTConsole.Data.Enumerations;
namespace NGDTConsole
{
    #region Longitude definition

    public struct Longitude
    {
        private readonly double east;
        private readonly double degree;
        private readonly double rev;
        private readonly double decDegree;

        public Longitude(double east, double degree, double rev)
        {
            this.east = east;
            this.degree = degree;
            this.rev = rev;
            this.decDegree = this.east + (this.degree / 60) + (this.rev/3600);    
        }

        public Longitude(double measurement, GeodeticMeasurementUnits unit)
        {
            if (unit.Equals(GeodeticMeasurementUnits.Radian))
            {
                double decDegree = measurement * (180.0 / Math.PI);
                double east = Math.Truncate(decDegree);
                double degree = Math.Truncate((decDegree - east) * 60);
                double rev = (((decDegree - east) * 60) - degree) * 60;
                this.decDegree = decDegree;
                this.degree = degree;
                this.east = east;
                this.rev = rev;
            }
            else
            {
                double decDegree = measurement;
                double east = Math.Truncate(decDegree);
                double degree = Math.Truncate((decDegree - east) * 60);
                double rev = (((decDegree - east) * 60) - degree) * 60;
                this.decDegree = decDegree;
                this.degree = degree;
                this.east = east;
                this.rev = rev;
            }
        }

        public double LongitudeDegreeDecimal
        {
            get { return this.decDegree; }
        }

        public double LongitudeRadian
        {
            get
            {
                return this.decDegree * Math.PI / 180.0;
            }
        }

        public double Easting
        {
            get
            {
                return this.east;
            }
        }

        public double Degree
        {
            get { return this.degree; }
        }

        public double Revolution
        {
            get { return this.rev; }
        }
    }

    #endregion

    #region Latitude definition

    public struct Latitude
    {
        private readonly double north;
        private readonly double degree;
        private readonly double rev;
        private readonly double decDegree;

        public Latitude(double north, double degree, double rev)
        {
            this.north = north;
            this.degree = degree;
            this.rev = rev;
            this.decDegree = this.north + (this.degree / 60) + (this.rev / 3600);            
        }

        public Latitude(double measurement, GeodeticMeasurementUnits unit)
        {
            if (unit.Equals(GeodeticMeasurementUnits.Radian))
            {
                double decDegree = measurement * (180.0 / Math.PI);
                double north = Math.Truncate(decDegree);
                double degree = Math.Truncate((decDegree - north) * 60);
                double rev = (((decDegree - north) * 60) - degree) * 60;
                this.decDegree = decDegree;
                this.degree = degree;
                this.north = north;
                this.rev = rev;
            }
            else
            {
                double decDegree = measurement;
                double east = Math.Truncate(decDegree);
                double degree = Math.Truncate((decDegree - east) * 60);
                double rev = (((decDegree - east) * 60) - degree) * 60;
                this.decDegree = decDegree;
                this.degree = degree;
                this.north = east;
                this.rev = rev;
            }
        }

        public double LatitudeDegreeDecimal
        {
            get { return this.decDegree; }
        }

        public double LatitudeRadian
        {
            get
            {
                return this.decDegree * Math.PI / 180.0;
            }
        }
    }
    
    #endregion
}
